//
//  STTVCommodityController.swift
//  iPhone
//
//  Created by Toj on 8/9/22.
//

import UIKit

class STTVCommodityController: STBaseCommodityController {
    
    public let viewModel = STCommodityTVViewModel()
    
    private var sectionModels: [STCommodityTVSectionModel] = [] { didSet {
        notDataView.isHidden = !sectionModels.isEmpty
        reloadInfo()
    } }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        viewModel.responseSections = { [weak self] sections in
            self?.view.hud.hide()
            self?.sectionModels = sections
        }
        
        setupMakeAddObserver()
        
        setupCollectionView()
        
        cardInfoRequest()
        
        setupMakeAddSubviews()
        
        bottomOffset = buyButtonHeight
    }
    
    override func registerCollectionViews() {
        super.registerCollectionViews()
        // 卡详情
        collectionView.register(TVCardDetailCell.cell_class, forCellWithReuseIdentifier: TVCardDetailCell.cell_identifier)
        
        // header
        collectionView.register(CommodityTitleView.cell_class, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: CommodityTitleView.cell_identifier)
        // footer
        collectionView.register(UICollectionReusableView.cell_class, forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: UICollectionReusableView.cell_identifier)
        
        // 充值详情
        collectionView.register(TVCommodityDetailCell.cell_class, forCellWithReuseIdentifier: TVCommodityDetailCell.cell_identifier)
        
        // 加购
        collectionView.register(TVCommodityPurchaseCell.cell_class, forCellWithReuseIdentifier: TVCommodityPurchaseCell.cell_identifier)
        
        // 支付渠道 header
        collectionView.register(STChannelHeaderView.cell_class, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: STChannelHeaderView.cell_identifier)
        // 支付渠道
        collectionView.register(STChannelCell.cell_class, forCellWithReuseIdentifier: STChannelCell.cell_identifier)
        // 支付渠道 - 银行卡
        collectionView.register(STChannelCardCell.cell_class, forCellWithReuseIdentifier: STChannelCardCell.cell_identifier)
        // 支付渠道 footer
        collectionView.register(STChannelFooterView.cell_class, forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: STChannelFooterView.cell_identifier)
        
        // 优惠券
        collectionView.register(TVCommodityCouponCell.cell_class, forCellWithReuseIdentifier: TVCommodityCouponCell.cell_identifier)
        
        // 服务列表
        collectionView.register(TVServiceCell.cell_class, forCellWithReuseIdentifier: TVServiceCell.cell_identifier)
        
        // 用户协议
        collectionView.register(MBCommodityServiceCell.cell_class, forCellWithReuseIdentifier: MBCommodityServiceCell.cell_identifier)
    }
    
    private func setupCollectionView() {
        
        collectionView.dataSource = self
        collectionView.delegate = self
    }
    
    internal override func reloadHeaderInfo() {
        headerView?.setMembershipInfo(segmentType: type, product: nil)
        showCouponAlert()
    }
    
    internal override func reloadInfo() {
        // 刷新数据
        collectionView.reloadData()
        reloadBuyNowInfo()
        reloadHeaderInfo()
    }
    
    internal override func changedWalletAmount() {
        viewModel.channelsSection.channelCellModel?.updateWalletChannelInfo()
        
        guard let selectedChannel = viewModel.channelsSection.channelCellModel?.selectedChannel else {
            return
        }
        collectionView.reloadData()
        guard selectedChannel.isEWallet else { return }
        reloadBuyNowInfo()
    }
    
    private lazy var buyNowView: TVPayFloatingView = {
        let view = TVPayFloatingView()
        view.backgroundColor = UIColor.white.st_alpha(0.96)
        view.delegate = self
        view.isHidden = true
        view.st_shadow()
        return view
    }()
    private let buyButtonHeight: CGFloat = 96.ui_scale
    private var couponAlertView: MBCouponAlert?
    
    deinit {
        print("-->toj: STTVCommodityController: deinit")
        NotificationCenter.default.removeObserver(self)
    }
}

extension STTVCommodityController {
    
    public func reloadCardDetail() {
        cardInfoRequest()
    }
    
    private func reloadBuyNowInfo() {
        buyNowView.channelViewModel = viewModel.channelsSection.channelCellModel?.selectedChannel
        buyNowView.couponCellModel = viewModel.couponSection.couponViewModel?.selectedCouponModel
        buyNowView.purchaseCellModel = viewModel.selectedAdditionalCommodity
        buyNowView.commodityCellModel = viewModel.selectedCommodity
        buyNowView.isHidden = buyNowView.channelViewModel == nil || buyNowView.commodityCellModel == nil || viewModel.cardSection.cardCellModel == nil
        
        showCouponAlert()
    }
    
    func showCouponAlert() {
        // 当前显示的是TV
        guard let headerSuperView = headerView?.superview,
              headerSuperView == collectionView && !view.isHidden, !buyNowView.isHidden else { return }
        
        // 有优惠券
        guard let _ = viewModel.couponSection.couponViewModel?.selectedCouponModel else { return }
        
        // 当天没显示
        guard !TimeCacheManager.manager.todayCache(type: .couponAlert)
        else { return }

        // 规格有效
        guard let commodity = buyNowView.commodityCellModel else { return }
        // 当天状态
        TimeCacheManager.manager.setTodayCache(type: .couponAlert)

        let couponAlert = MBCouponAlert()
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate, let window = appDelegate.window else { return }

        let toPosition = window.convert(buyNowView.actualPriceLabel.center, from: buyNowView)
        couponAlert.toPosition = toPosition
        couponAlert.tvModel = commodity
        couponAlert.delegate = self

        view.superview?.addSubview(couponAlert)
        couponAlert.frame = view.bounds
        couponAlert.animationCoupon()
        couponAlertView = couponAlert
    }
    
    private func gotoBuyPay(commodity: TVCommodityCellModel, channel: STChannelCellModel, additionalCommodity: TVAdditionalCommodityCellModel?) {
        print("-->toj: " + #function)
        guard let commodity = viewModel.selectedCommodity else { return }
        guard let channel = viewModel.channelsSection.channelCellModel?.selectedChannel else { return }
        guard let smartcardModel = viewModel.cardSection.cardCellModel else { return }
        let smartcard = smartcardModel.cardNumber
        
        let coupon = viewModel.couponSection.couponViewModel?.selectedCouponModel
        DVBOrderPayManager.manager.orderBuy(smartcard: smartcard, commodity: commodity, additionalCommodity: viewModel.selectedAdditionalCommodity, couponModel: coupon, completion: { [weak self] order, state in
            // 下单失败
            if state.isFailed {
                self?.cardInfoRequest()
                return
            }
            
            // 价钱为0直接退出了不需要支付
            if state == .successPay { return }
            // 延迟0.25 等待页面动画结束后更新
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
                self?.cardInfoRequest()
            }
            guard let orderInfo = order else { return }
            // 支付
            STOrderPayManager.manager.orderPay(channel: channel, order: orderInfo) { order, state in
                
            }
        })
    }
    
    private func didTapBuyPay() {
        if !STUserModel.shared.isRealUser() {
            STAlertHelper.manager.show(message: "alert_login".localized(), title: "notice_".localized(), defalutButton: "confirm_".localized(), cancelButton: "cancel_".localized(), isCancel: true, inView: self.view, defaultAction: {
                STSRouter.openLocalPage(RouterPage.login)
            })
            return
        }
        
        guard let commodity = viewModel.selectedCommodity,
              let channel = viewModel.channelsSection.channelCellModel?.selectedChannel else { return }
        gotoBuyPay(commodity: commodity, channel: channel, additionalCommodity: viewModel.selectedAdditionalCommodity)
    }
}

// MARK: - 点击事件/ 通知回调
extension STTVCommodityController {
    
   // 开关改变
   @objc func didChangeFunction() {
       viewModel.resetupServicesSection()
       collectionView.reloadData()
   }
   
   // 充值
   @objc func didRecharged() {
       cardInfoRequest()
   }
   
   // 换包
   @objc func didChangeBouquet() {
       cardInfoRequest()
   }
   
   // 绑卡
   @objc func didChangeLinked() {
       cardInfoRequest()
   }
}

// MARK: - 数据请求
extension STTVCommodityController {
    
    // 请求ott服务 获取卡号, 再请求卡详情
    private func cardInfoRequest() {
        view.hud.enabled(false).show()
        viewModel.requestCardInfo(completion: { [weak self] isSuccess, message in
            self?.headerView?.isLinkCard = OTTService.shared.activedPackage != nil
            self?.reloadInfo()
        })
    }
    
    private func unlinkRequest() {
        view.hud.show()
        viewModel.requestUnlink(completion: { [weak self] isSuccess in
            self?.view.hud.hide()
            if isSuccess {
                NotificationCenter.default.post(name: .ServiceRightsDidChange, object: RightsChangeState.DVBRightEnd, userInfo: nil)
                self?.reloadInfo()
                self?.view.showToast(message: OLLocalize("deactivate_successful"))
                // 刷新卡状态
                self?.cardInfoRequest()
                return
            }
            self?.headerView?.isLinkCard = !isSuccess
            self?.view.showToast(message: OLLocalize("deactivate_failed"))
        })
    }
}

extension STTVCommodityController: TVPayFloatingViewDelegate {
    func payFloatingViewDidTapBuyNow(_ view: TVPayFloatingView) {
        didTapBuyPay()
    }
}

extension STTVCommodityController: MBCouponAlertDelegate {
    
    func couponAlertDidTapWillClose(view: MBCouponAlert) {
        guard let commodity = buyNowView.commodityCellModel else { return }
        buyNowView.actualPriceLabel.text = String(commodity.startPrice)
    }

    func couponAlertDidTapClose(view: MBCouponAlert) {
        couponAlertView?.removeFromSuperview()
        guard let commodity = buyNowView.commodityCellModel else { return }
        
        let price = commodity.startPrice
        let finalPrice = commodity.endPrice
        buyNowView.startAnimationPrice(price, to: finalPrice)
        couponAlertView = nil
    }
}

// MARK: - 代理事件 TVCommodityPurchaseCellDelegate
extension STTVCommodityController: TVCommodityPurchaseCellDelegate {
    func commodityPurchaseCell(_ view: TVCommodityPurchaseCell, didSelected commodity: TVAdditionalCommodityCellModel) {
        if viewModel.selectedAdditionalCommodity == commodity {
            viewModel.selectedAdditionalCommodity = nil
            reloadBuyNowInfo()
            collectionView.reloadData()
            return
        }
        viewModel.selectedAdditionalCommodity = commodity
        reloadBuyNowInfo()
        collectionView.reloadData()
    }
}

extension STTVCommodityController: TVCardDetailCellDelegate {
    
    func cardDetailCellDidTapUnlink() {
        UIHelper.showAlert(title: OLLocalize("tips", comment: ""), message: OLLocalize("deactivate_notice", comment: ""), defaultTitle: OLLocalize("deactivate", comment: ""), cancelTitle: OLLocalize("cancel", comment: ""), in: nil, defaultAction: {[weak self] in
            self?.unlinkRequest()
        }, cancelAction: nil, presentCompletion: nil)
    }
    
    func cardDetailCellDidTapPreOtherCard(_ view: TVCardDetailCell) {
        reloadCardDetail()
        DataStatistics.shared.ds_linkOther()
    }
    
    func cardDetailCell(_ view: TVCardDetailCell, didTapPrelinkCard activity: ActivityModel) {
        DVBService.shared.requestSmartcardOneLink(activity: activity) { [weak self] cardInfo, code in
            var info = cardInfo
            info?.fixValues(activity: activity)
            self?.responceSmartcardOneLink(cardInfo: info, code: code)
            guard code.isSuccess else { return }
            self?.reloadCardDetail()
        }
    }
    
    private func responceSmartcardOneLink(cardInfo: CardPreLinkInfo?, code: CardPreLinkCode) {
        var info = cardInfo
        let result = code.result
        let alert = LinkingCardResultAlert()
        alert.resultCategory = .dvbservice
        alert.cardInfo = cardInfo
        alert.result = result
        STAlertHelper.manager.show(alert: alert, inView: self.view.superview)
        
        DataStatistics.shared.ds_linkResult(category: .dvbservice, action: .linkResultShow, label: .none, value: result.rawValue, msg: info?.ds_ext)
    }
}

// MARK: - 代理事件 TVCommodityDetailCellDelegate
extension STTVCommodityController: TVCommodityDetailCellDelegate {

    func commodityDetailCell(_ view: TVCommodityDetailCell, didTapAmount index: Int, amount: Int) {
        viewModel.setupCoupon(for: index)
        reloadBuyNowInfo()
        collectionView.reloadData()
    }
    
    func commodityDetailCell(_ view: TVCommodityDetailCell, didSelected commodity: TVCommodityCellModel) {
        viewModel.setupCouponAndNumberIndex(for: commodity)
        reloadBuyNowInfo()
        collectionView.reloadData()
    }
}

// MARK: - 代理事件 MBChannelCellDelegate
extension STTVCommodityController: STChannelCellDelegate {
    
    func channelCellDidTapSelected(_ view: STChannelCell) {
        viewModel.channelsSection.channelCellModel?.selectedChannel = view.model
        reloadBuyNowInfo()
        collectionView.reloadData()
    }
}

// MARK: - 代理事件 MBChannelCardCellDelegate
extension STTVCommodityController: STChannelCardCellDelegate {
    
    func channelCardCellDidTapSelected(_ view: STChannelCardCell) {
        viewModel.channelsSection.channelCellModel?.selectedChannel = view.model
        reloadBuyNowInfo()
        collectionView.reloadData()
    }
    
    func channelCardCellDidTapAddCard(_ view: STChannelCardCell) {
        if !STUserModel.shared.isRealUser() {
            STAlertHelper.manager.show(message: "alert_login".localized(), title: "notice_".localized(), defalutButton: "confirm_".localized(), cancelButton: "cancel_".localized(), isCancel: true, inView: self.view, defaultAction: {
                STSRouter.openLocalPage(RouterPage.login)
            })
            return
        }
        
        guard let commodity = viewModel.selectedCommodity,
              let channel = view.model else { return }
        gotoBuyPay(commodity: commodity, channel: channel, additionalCommodity: viewModel.selectedAdditionalCommodity)
    }
}

// MARK: - 代理事件 STChannelFooterViewDelegate
extension STTVCommodityController: STChannelFooterViewDelegate {
    
    func channelFooterView(_ view: STChannelFooterView, didTapControl button: UIButton) {
        guard let sectionIndex = view.tvViewModel?.sectionIndex else { return }
       
        collectionView.reloadData()
        if button.isSelected { return }
        guard collectionView.numberOfSections > sectionIndex else { return }
        
        collectionView.scrollToItem(at: IndexPath(row: 0, section: sectionIndex), at: .centeredVertically, animated: true)
    }
}

// MARK: - 代理事件 TVCommodityCouponCellDelegate
extension STTVCommodityController: TVCommodityCouponCellDelegate {
    
    func commodityCouponCellDidTapCoupons(_ view: TVCommodityCouponCell) {
        let vc = TVCouponsViewController()
        vc.vc_delegate = self
        vc.coupons = view.cellModel?.cellModels ?? []
        vc.modalPresentationStyle = .custom
        present(vc, animated: false, completion: nil)
    }
}

// MARK: - 代理事件 TVCouponsViewControllerDelegate
extension STTVCommodityController: TVCouponsViewControllerDelegate {
    
    func couponsViewController(_ viewController: TVCouponsViewController, couponCellModel: TVCouponCellModel?) {
        viewModel.setupNumberIndex(for: couponCellModel)
        reloadBuyNowInfo()
        collectionView.reloadData()
    }
}

// MARK: - 代理事件 UICollectionViewDataSource
extension STTVCommodityController: UICollectionViewDataSource {
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return sectionModels.count
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        let sectionModel = sectionModels[section]
        
        // 卡信息
        // 规格
        // 服务协议
        if sectionModel.type == .card ||
            sectionModel.type == .commodity ||
            sectionModel.type == .serviceAgreement {
            return 1
        }
        
        // 优惠券
        if sectionModel.type == .coupon  {
            guard let couponViewModel = sectionModel.couponViewModel else { return 0 }
            return couponViewModel.cellModels.isEmpty ? 0 : 1
        }
        
        // 加购
        if sectionModel.type == .purchase {
            return sectionModel.purchaseCellModel == nil ? 0 : 1
        }
        
        // 支付渠道
        if sectionModel.type == .payChannel {
            return sectionModel.channelCellModel?.showChannels.count ?? 0
        }
        
        if sectionModel.type == .services {
            return sectionModel.services.count
        }
        
        return 0
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let sectionModel = sectionModels[indexPath.section]
        if sectionModel.type == .card {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TVCardDetailCell.cell_identifier, for: indexPath, TVCardDetailCell.self)
            cell.model = sectionModel.cardCellModel
            cell.delegate = self
            return cell
        }
        
        if sectionModel.type == .commodity {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TVCommodityDetailCell.cell_identifier, for: indexPath, TVCommodityDetailCell.self)
            cell.delegate = self
            cell.cellModel = sectionModel.produtctCellModel
            return cell
        }
        
        // 加购
        if sectionModel.type == .purchase {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TVCommodityPurchaseCell.cell_identifier, for: indexPath, TVCommodityPurchaseCell.self)
            cell.cellModel = sectionModel.purchaseCellModel
            cell.delegate = self
            return cell
        }
        
        // 支付渠道
        if sectionModel.type == .payChannel {
            let channel = sectionModel.channelCellModel?.showChannels[indexPath.row]
            if channel?.isCarCell == true {
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: STChannelCardCell.cell_identifier, for: indexPath, STChannelCardCell.self)
                cell.delegate = self
                cell.model = channel
                return cell
            }
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: STChannelCell.cell_identifier, for: indexPath, STChannelCell.self)
            cell.model = channel
            cell.delegate = self
            return cell
        }

        // 优惠券
        if sectionModel.type == .coupon {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TVCommodityCouponCell.cell_identifier, for: indexPath, TVCommodityCouponCell.self)
            cell.cellModel = sectionModel.couponViewModel
            cell.delegate = self
            return cell
        }
        
        // 服务协议
        if sectionModel.type == .serviceAgreement {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MBCommodityServiceCell.cell_identifier, for: indexPath, MBCommodityServiceCell.self)
            return cell
        }

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TVServiceCell.cell_identifier, for: indexPath, TVServiceCell.self)
        cell.model = sectionModel.services[indexPath.row]
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

        let sectionModel = sectionModels[indexPath.section]
        if kind == UICollectionView.elementKindSectionHeader {
            if sectionModel.type == .payChannel {
                // 为了定位支付渠道 在那个分区, 点击footer后滚动到上面
                sectionModel.channelCellModel?.sectionIndex = indexPath.section
                let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: STChannelHeaderView.cell_identifier, for: indexPath) as? STChannelHeaderView
                view?.tvSection = sectionModel
                return view!
            }

            let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: CommodityTitleView.cell_identifier, for: indexPath) as? CommodityTitleView
            view?.backgroundColor = .white
            view?.section = sectionModel
            return view!
        }

        if sectionModel.type == .payChannel {
            let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: STChannelFooterView.cell_identifier, for: indexPath) as? STChannelFooterView
            view?.tvViewModel = sectionModel.channelCellModel
            view?.delegate = self
            return view!
        }

        let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: UICollectionReusableView.cell_identifier, for: indexPath)
        view.backgroundColor = "#EEEEEE".to_color
        return view
    }
}

// MARK: - 代理事件 UICollectionViewDelegateFlowLayout
extension STTVCommodityController: UICollectionViewDelegateFlowLayout {
    
    // section 上下左右的间距
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        let sectionModel = sectionModels[section]
        return sectionModel.layoutEdgeinset
    }
    
    // cell 大小
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let sectionModel = sectionModels[indexPath.section]
        return sectionModel.cellSize
    }
    
    // section header 大小
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        let sectionModel = sectionModels[section]
        return sectionModel.headerSize
    }
    
    // section footer 大小
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
        
        if section == collectionView.numberOfSections-1 {
            return STDefaultCellSize
        }
        
        let sectionModel = sectionModels[section]
        return sectionModel.footerSize
    }
    
    // cell之间 垂直间距
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        let sectionModel = sectionModels[section]
        return sectionModel.minimumLineSpacing
    }
    
    // cell之间 水平间距
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        let sectionModel = sectionModels[section]
        return sectionModel.minimumInteritemSpacing
    }
}

// MARK: - 初始化
extension STTVCommodityController {
    
    private func setupMakeAddObserver() {
        // 换包
        NotificationCenter.default.addObserver(self, selector:#selector(didChangeBouquet), name:.serviceDidChangeBouquet, object:nil)
        
        // 充值
        NotificationCenter.default.addObserver(self, selector:#selector(didRecharged), name:.serviceDidRecharged, object:nil)
        
        // 绑卡
        NotificationCenter.default.addObserver(self, selector:#selector(didChangeLinked), name:.serviceDidLinkedCard, object:nil)
        
        // 开关改变
        NotificationCenter.default.addObserver(self, selector:#selector(didChangeFunction), name:.AppFunctionDidChange, object:nil)
    }
    
    private func setupMakeAddSubviews() {
        view.addSubview(buyNowView)
        buyNowView.snp.makeConstraints { make in
            make.left.right.bottom.equalTo(view)
            make.height.equalTo(buyButtonHeight)
        }
    }
}
